#include "business.h"
#include "../3party/PubSubClient.h"

#include <ESP8266WiFi.h>

/**** 服务器配置定义 ****/
char gBemfaKey[32] = {0};
char gTopicInput[32] = {0};
char gTopicOutput[32] = {0};

/**** 指令定义 ****/
#define ESP_ONLINE "ESP:ONLINE"
#define ACK_OK "ACK:OK"
#define ACK_ERROR "ACK:ERROR"

static WiFiClient gEspClient;
static PubSubClient gMqttClient(gEspClient);
static WifiManager *gWifiManager;

/**** 函数声明 ****/
void mqttMsgCallback(char *topic, byte *payload, unsigned int length);

void mqttClientInit(         // 传参
    const char *domain,      // 巴法MQTT服务器地址
    unsigned int port,       // 巴法MQTT服务器端口
    const char *key,         // 巴法密钥
    const char *inputTopic,  // 指令输入话题
    const char *outputTopic, // 反馈接收话题
    WifiManager *pManager)
{
    // 数值拷贝
    memcpy(gBemfaKey, key, sizeof(gBemfaKey));
    memcpy(gTopicInput, inputTopic, sizeof(gTopicInput));
    memcpy(gTopicOutput, outputTopic, sizeof(gTopicOutput));

    // 配置mqtt客户端
    gMqttClient.setServer(domain, port);
    gMqttClient.setCallback(mqttMsgCallback);
    gWifiManager = pManager;
}

/*
 * mqtt回调函数
 */
void mqttMsgCallback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i = 0; i < length; i++)
    {
        Serial.print((char)payload[i]);
    }
    Serial.println();

    char *cstring = (char *)payload;
    cstring[length] = '\0';
    // Serial.println(cstring);

    if ((strcmp(cstring, "ON") == 0) && (strcmp(topic, gTopicInput) == 0))
    {
        if (gWifiManager->doWol())
        {
            Serial.println(ACK_OK);
            gMqttClient.publish(gTopicOutput, ACK_OK);
        }
        else
        {
            gMqttClient.publish(gTopicOutput, ACK_ERROR);
        }
    }
    else
    {
        gMqttClient.publish(gTopicOutput, ACK_ERROR);
    }
}

/*
 * mqtt重连函数
 */
void mqttClientLoop()
{
    // mqtt重连
    if (!gMqttClient.connected())
    {
        Serial.print("Attempting MQTT connection...");
        if (gMqttClient.connect(gBemfaKey))
        {
            Serial.println("mqtt success connected!");
            gMqttClient.publish(gTopicOutput, ESP_ONLINE);
            gMqttClient.subscribe(gTopicInput);
        }
        else
        {
            Serial.print("failed, rc=");
            Serial.print(gMqttClient.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }
    else
    {
        gMqttClient.loop();
    }
}